﻿using System;
using System.Collections.Generic;
using System.Data.Entity.Core;
using System.Data.Entity.SqlServer;
using System.Linq;
using System.Net.Http;
using System.Web;
using System.Web.UI;
using Newtonsoft.Json;

namespace WebServiceTMS.Helpers
{
    public class TMSTask
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
        public string GoalName { get; set; }
        public string GoalId { get; set; }
        public string AssignedToName { get; set; }
        public string AssignedToId { get; set; }
        public string Status { get; set; }
        public string StartDate { get; set; }
        public string FinishDate { get; set; }
        public string CreatedByName { get; set; }
        public string CreatedById { get; set; }
        public string PriorityStr { get; set; }
        public int PriorityVal { get; set; }
    }
    public class TaskHelper
    {
        public static HttpResponseMessage AddNewTaskHelper(int userId, int goalId, string name, string description,
            int assignedTo, int priority, DateTime startDate, DateTime finishDate)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var newTask = new Tasks
                    {
                        Goal = goalId,
                        Name = name,
                        Description = description,
                        Priority = priority,
                        StartDate = startDate,
                        FinishDate = finishDate,
                        Status = "To Do"
                    };
                    var users = context.Users.ToList();
                    if (users.FirstOrDefault(u => u.Id == userId) != null)
                        newTask.CreatedBy = userId;
                    if (assignedTo != 0)
                        if (users.FirstOrDefault(u => u.Id == assignedTo) != null)
                            newTask.AssignedTo = assignedTo;
                    context.Tasks.Add(newTask);
                    context.SaveChanges();
                    return HttpResponseHelper.CreateHttpResponse("success", "");
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        public static HttpResponseMessage RemoveTaskHelper(int userId, int taskId)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var user = context.Users.FirstOrDefault(u => u.Id == userId);
                    if (user != null)
                    {
                        var task = context.Tasks.FirstOrDefault(t => t.Id == taskId);
                        if (task != null)
                        {
                            if (user.Status == "Admin" || user.Status == "Manager" || task.CreatedBy == user.Id)
                            {
                                context.Tasks.Remove(task);
                                context.SaveChanges();
                                return HttpResponseHelper.CreateHttpResponse("success", "");
                            }
                            return HttpResponseHelper.CreateHttpResponse("error", "You have no permissions to remove this task");
                        }
                        return HttpResponseHelper.CreateHttpResponse("error", "There is no such task in the system");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "Invalid user");
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        public static HttpResponseMessage GetAllTasksInGoalHelper(int goalId)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var users = context.Users.ToList();
                    var allGoals = context.Goals.ToList();
                    var query = from t in context.Tasks
                                where t.Goal == goalId
                                select new TMSTask
                                {
                                    Id = SqlFunctions.StringConvert((double)t.Id).Trim(),
                                    Name = t.Name,
                                    Description = t.Description,
                                    GoalName = allGoals.First(g => g.Id == goalId).Name,
                                    GoalId = SqlFunctions.StringConvert((double)allGoals.First(g => g.Id == goalId).Id).Trim(),
                                    AssignedToName = users.FirstOrDefault(u => u.Id == t.AssignedTo).Login, //TODO exception when is null
                                    AssignedToId = SqlFunctions.StringConvert((double)t.AssignedTo).Trim(),
                                    Status = t.Status,
                                    StartDate = t.StartDate.ToShortDateString(),
                                    FinishDate = t.FinishDate.ToShortDateString(),
                                    CreatedByName = users.FirstOrDefault(u => u.Id == t.CreatedBy).Login, //TODO exception when is null
                                    CreatedById = SqlFunctions.StringConvert((double)t.CreatedBy).Trim(),
                                    PriorityStr = StringGenerator.GetPriorityString(t.Priority),
                                    PriorityVal = t.Priority
                                };
                    return GetJsonTasks(query.ToArray());
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        public static HttpResponseMessage GetAllUserTasksHelper(int userId)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var users = context.Users.ToList();
                    var allGoals = context.Goals.ToList();
                    var query = from t in context.Tasks
                                where t.CreatedBy == userId ||
                                t.AssignedTo == userId
                                select new TMSTask
                                {
                                    Id = SqlFunctions.StringConvert((double)t.Id).Trim(),
                                    Name = t.Name,
                                    Description = t.Description,
                                    GoalName = allGoals.First(g => g.Id == t.Goal).Name,
                                    GoalId = SqlFunctions.StringConvert((double)allGoals.First(g => g.Id == t.Goal).Id).Trim(),
                                    AssignedToName = users.FirstOrDefault(u => u.Id == t.AssignedTo).Login, //TODO exception when is null
                                    AssignedToId = SqlFunctions.StringConvert((double)t.AssignedTo).Trim(),
                                    Status = t.Status,
                                    StartDate = t.StartDate.ToShortDateString(),
                                    FinishDate = t.FinishDate.ToShortDateString(),
                                    CreatedByName = users.FirstOrDefault(u => u.Id == t.CreatedBy).Login, //TODO exception when is null
                                    CreatedById = SqlFunctions.StringConvert((double)t.CreatedBy).Trim(),
                                    PriorityStr = StringGenerator.GetPriorityString(t.Priority),
                                    PriorityVal = t.Priority
                                };
                    return GetJsonTasks(query.ToArray());
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        public static HttpResponseMessage EditTaskDescriptionHelper(int taskId, string description)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var task = context.Tasks.FirstOrDefault(t => t.Id == taskId);
                    if (task != null)
                    {
                        task.Description = description;
                        context.SaveChanges();
                        return HttpResponseHelper.CreateHttpResponse("success", "");
                    }
                    return HttpResponseHelper.CreateHttpResponse("error", "There is no such task in the system");
                }
            }
            catch (Exception ex)
            {
                return HttpResponseHelper.CreateHttpResponse("server_error", ex.Message);
            }
        }

        public static HttpResponseMessage GetJsonTasks(TMSTask[] taskList)
        {
            if (taskList.Any())
            {
                for (var i = 0; i < taskList.Count(); i++)
                {
                    taskList[i].Id = TMSCryptography.Encrypt(taskList[i].Id);
                    taskList[i].AssignedToId = TMSCryptography.Encrypt(taskList[i].AssignedToId);
                    taskList[i].CreatedById = TMSCryptography.Encrypt(taskList[i].CreatedById);
                }
                var jsonResponse = JsonConvert.SerializeObject(taskList);
                return HttpResponseHelper.CreateHttpResponse("success", jsonResponse);
            }
            return HttpResponseHelper.CreateHttpResponse("success", "[]");
        }
        /*
        public static TMSTask[] GetAllTasksInGoal(int goalId)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var query = from t in context.Tasks
                                join g in context.Goals on t.Goal equals g.Id
                                join assignedTo in context.Users on t.AssignedTo equals assignedTo.Id
                                join createdBy in context.Users on t.CreatedBy equals createdBy.Id
                                where t.Goal == goalId
                                select new TMSTask
                                {
                                    Id = SqlFunctions.StringConvert((double)t.Id).Trim(),
                                    Name = t.Name,
                                    Description = t.Description,
                                    GoalName = g.Name,
                                    GoalId = SqlFunctions.StringConvert((double)g.Id).Trim(),
                                    AssignedToName = assignedTo.Login, //TODO exception when is null
                                    AssignedToId = SqlFunctions.StringConvert((double)t.AssignedTo).Trim(),
                                    Status = t.Status,
                                    StartDate = t.StartDate.ToShortDateString(),
                                    FinishDate = t.FinishDate.ToShortDateString(),
                                    CreatedByName = createdBy.Login, //TODO exception when is null
                                    CreatedById = SqlFunctions.StringConvert((double)t.CreatedBy).Trim(),
                                    PriorityStr = StringGenerator.GetPriorityString(t.Priority),
                                    PriorityVal = t.Priority
                                };
                    return query.ToArray();
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Server error: " + ex.Message);
            }
        }

        public static TMSTask GetTask(int taskId)
        {
            try
            {
                using (var context=new TMSEntities())
                {
                    var task = (from t in context.Tasks
                        join g in context.Goals on t.Goal equals g.Id
                        join assignedTo in context.Users on t.AssignedTo equals assignedTo.Id
                        join createdBy in context.Users on t.CreatedBy equals createdBy.Id
                        where t.Id == taskId
                        select new TMSTask
                        {
                            Id = SqlFunctions.StringConvert((double)t.Id).Trim(),
                            Name = t.Name,
                            Description = t.Description,
                            GoalName = g.Name,
                            GoalId = SqlFunctions.StringConvert((double)g.Id).Trim(),
                            AssignedToName = assignedTo.Login, //TODO exception when is null
                            AssignedToId = SqlFunctions.StringConvert((double)t.AssignedTo).Trim(),
                            Status = t.Status,
                            StartDate = t.StartDate.ToShortDateString(),
                            FinishDate = t.FinishDate.ToShortDateString(),
                            CreatedByName = createdBy.Login, //TODO exception when is null
                            CreatedById = SqlFunctions.StringConvert((double)t.CreatedBy).Trim(),
                            PriorityStr = StringGenerator.GetPriorityString(t.Priority),
                            PriorityVal = t.Priority
                        }).SingleOrDefault();
                    return task;
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Server error: " + ex.Message);
            }
        }

        public static void RemoveTask(int userId, int taskId)
        {
            try
            {
                using (var context=new TMSEntities())
                {
                    var user = context.Users.SingleOrDefault(u => u.Id == userId);
                    if (user != null)
                    {
                        var task = context.Tasks.SingleOrDefault(t => t.Id == taskId);
                        if (task != null)
                        {
                            if (user.Status == "Admin" || user.Status == "Manager" || task.CreatedBy == user.Id)
                            {
                                context.Tasks.Remove(task);
                                context.SaveChanges();
                            }
                            throw new Exception("You have no permissions to remove this task");
                        }
                        throw new Exception("There is no such task in the system");
                    }
                    throw new Exception("Invalid user");
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Server error: " + ex.Message);
            }
        }

        public static void AddNewTask(int userId, int goalId, string name, string description,
            int assignedTo, int priority, DateTime startDate, DateTime finishDate)
        {
            try
            {
                using (var context = new TMSEntities())
                {
                    var newTask = new Tasks
                    {
                        Goal = goalId,
                        Name = name,
                        Description = description,
                        Priority = priority,
                        StartDate = startDate,
                        FinishDate = finishDate,
                        Status = "To Do"
                    };
                    var users = context.Users.ToList();
                    if (users.FirstOrDefault(u => u.Id == userId) != null)
                        newTask.CreatedBy = userId;
                    if (assignedTo != 0)
                        if (users.FirstOrDefault(u => u.Id == assignedTo) != null)
                            newTask.AssignedTo = assignedTo;
                    context.Tasks.Add(newTask);
                    context.SaveChanges();
                }
            }
            catch (Exception ex)
            {
                throw new Exception("Server error: " + ex.Message);
            }
        }*/
    }
}